#pragma once
#include "mdqp.hpp"
#include "log.hpp"
#include "mirp.hpp"

#include <map>
#include <vector>
#include <atomic>
#include <memory>
#include <set>

namespace Market
{
    namespace
    {
        // 合约
        class Instrument
        {
        private:
            // 缓存的数据是从 分价表变动域开始的
            std::map<int32_t, std::vector<uint8_t>> m_cached_incremental_data;

        public:
            int32_t m_instrument_no; // 合约编号

            // 这个值的初始值是在 MDQP 中设置的，当该值被设置时，
            // 需要根据已经缓存的 MIRP 的值进行合约数据的更新
            int32_t m_current_snapshot_no; // 当前合约的快照编号
            InstrumentInfoResponse m_instrument_info;
            InstrumentTradingInfoResponse m_instrument_trading_info;

        public:
            Instrument() = delete;
            Instrument(int32_t instrument_no) : m_instrument_no(instrument_no),
                                                m_current_snapshot_no(-1)
            {
            }
            Instrument(int32_t instrument_no,
                       int32_t snapshot_no) : m_instrument_no(instrument_no),
                                              m_current_snapshot_no(snapshot_no)
            {
            }
            void update(uint8_t const *p, uint8_t const *const end);
            void cache(int32_t snapshot_no, uint8_t *data, size_t len);
            void proceeCachedIncrementalData(int32_t snapshot_no);
        };

        // 主题行情
        class TopicMarket
        {
        public:
            int32_t m_topic_id;            // 主题编号
            int32_t m_current_snapshot_no; // 主题行情的快照编号
            int32_t m_packet_no;           // 主题增量行情编号
            std::set<int32_t> m_instrument_no;

        public:
            TopicMarket(/* args */) = delete;
            TopicMarket(int32_t topic_id,
                        int32_t snapshot_no) : m_topic_id(topic_id),
                                               m_current_snapshot_no(snapshot_no)
            {
            }
            void addInstrument(int32_t instrument_no)
            {
                m_instrument_no.insert(instrument_no);
            }
            ~TopicMarket() {}
        };

    } // namespace

    class Market
    {
    private:
        std::map<int32_t, std::shared_ptr<TopicMarket>> m_topic_markets;
        std::map<int32_t, std::shared_ptr<Instrument>> m_instruments;

        void parseMDQP_Snapshot(MDQPHeader const *const mdqp_header);
        void parseMIRP_Incremental(MIRPHeader const *const mirp_header);

    public:
        Market(/* args */) {}
        ~Market() {}
        void parseMIRP(const MIRPHeader *const mirp_header)
        {
            switch (mirp_header->type_id)
            {
            case 0x00:
                // LOG("MIRP: Heartbeat\n");
                break;
            case 0x01:
                // LOG("MIRP: 增量行情刷新消息\n");
                parseMIRP_Incremental(mirp_header);
                break;
            default:
                LOG("MIRP: Unknown TypeID\n");
                break;
            }
        }
        void parseMDQP(uint8_t *data, size_t data_len)
        {
            // 只有 login response 和 快照查询应答 两种类型的报文
            MDQPHeader *mdqp_header = (MDQPHeader *)data;
            switch (mdqp_header->type_id)
            {
            case 0x00:
                // LOG("MDQP: Heartbeat\n");
                break;
            case 0x11:
                LOG("MDQP: Login Request\n");
                break;
            case 0x12:
                LOG("MDQP: Login Response\n");
                break;
            case 0x13:
                LOG("MDQP: Logout Request\n");
                break;
            case 0x14:
                LOG("MDQP: Logout Response\n");
                break;
            case 0x31:
                LOG("MDQP: 快照查询请求\n");
                break;
            case 0x32:
                // LOG("MDQP: 快照查询应答\n");
                // parseMDQP_Snapshot(mdqp_header);
                break;
            case 0x33:
                LOG("MDQP: 增量查询请求\n");
                break;
            case 0x34:
                LOG("MDQP: 增量查询应答\n");
                break;
            default:
                LOG("MDQP: Unknown TypeID\n");
                break;
            }
        }
    };
} // namespace Market
